package com.zm.zmgz.service;

import com.zm.zmgz.dao.MetadataBeanMapper;
import com.zm.zmgz.pojo.MetadataBean;
import com.zm.zmgz.pojo.MetadataBeanExample;
import com.zm.zmgz.utils.StringCjwUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Created with IntelliJ IDEA.
 *
 * @Auther: cjw
 * @Date: 2020/05/11/12:39
 * @Description:
 */
@Service
public class MetadataService {

    @Autowired
    MetadataBeanMapper metadataBeanMapper;

    /***
     * @Description: 获取所有节点;对根节点进行包装,数据库中并没有体现根节点.
     * 首先创建一个根节点,然后进行填充子节点(递归填充)
     * @Param:
     * @return:
     * @Author: cjw
     * @Date: 2020-05-11 12:41:52
     */
    public MetadataBean getAllNode() {
        // 创建一个根节点
        MetadataBean metadataBean = new MetadataBean();
        metadataBean.setPath("/");
        metadataBean.setName("/");
        metadataBean.setChinesename("/");
        // 递归填充填充子节点
        getChildNode(metadataBean);
        return metadataBean.getChildrenNodes() == null ? null : metadataBean;
    }

    /***
     * @Description: 递归填充子节点
     * 创建List<MetadataBean>
     * 获取所有子节点,添加到List<MetadataBean>,并且所有子节点都调用本方法,参数为自己
     *
     * @Param:
     * @return:
     * @Author: cjw
     * @Date: 2020-05-11 12:48:51
     */
    private void getChildNode(MetadataBean metadataBean) {
        // 创建List<MetadataBean>
        List<MetadataBean> metadataBeanList = new ArrayList<>();

        // 获取所有子节点
        String path = metadataBean.getPath();
        MetadataBeanExample metadataBeanExample = new MetadataBeanExample();
        MetadataBeanExample.Criteria criteria = metadataBeanExample.createCriteria();
        if (!metadataBean.getName().equals("/")) { // 根节点的子节点path为"/",不需要拼接
            criteria.andPathEqualTo(path + metadataBean.getName() + "/");
        } else {
            criteria.andPathEqualTo("/");
        }
        metadataBeanExample.setOrderByClause("name");
        List<MetadataBean> metadataBeanList1 = metadataBeanMapper.selectByExample(metadataBeanExample);
        if (!Objects.isNull(metadataBeanList1) && metadataBeanList1.size() > 0) {
            // 所有子节点都调用本方法,参数为自己
            for (MetadataBean bean : metadataBeanList1) {
                getChildNode(bean);
            }
            // 获取所有子节点,添加到List<MetadataBean>
            metadataBean.setChildrenNodes(metadataBeanList1);
        } else {
            metadataBean.setChildrenNodes(null);
        }

    }

    /***
     * @Description: 添加节点
     * 参数检查
     * - path：该path存在，或为“/”
     * - name，chineseName：同path下唯一，并且不能为“/”
     * @Param:
     * @return:
     * @Author: cjw
     * @Date: 2020-05-11 14:02:07
     * @param metadataBean
     */
    public int addNode(MetadataBean metadataBean) {
        // 节点名不允许为"/"
        if (metadataBean.getName().equals("/") || metadataBean.getChinesename().equals("/")) {
            return 0;
        }
        // 非一级子节点,需要验证父节点是否存在
        MetadataBean parentNode = new MetadataBean();
        if (!metadataBean.getPath().equals("/")) {
            parentNode.setPath(StringCjwUtils.getParentPath(metadataBean.getPath()));
            parentNode.setName(StringCjwUtils.getPathName(metadataBean.getPath()));
            MetadataBeanExample metadataBeanExample = new MetadataBeanExample();
            MetadataBeanExample.Criteria criteria = metadataBeanExample.createCriteria();
            criteria.andPathEqualTo(parentNode.getPath()).andNameEqualTo(parentNode.getName());
            List<MetadataBean> metadataBeanList = metadataBeanMapper.selectByExample(metadataBeanExample);
            if (Objects.isNull(metadataBeanList) || metadataBeanList.size() == 0)
                return 0;
        }
        // 在父节点存在情况下,验证该节点名是否已存在(节点不允许重复添加)
        MetadataBeanExample metadataBeanExample = new MetadataBeanExample();
        MetadataBeanExample.Criteria criteria = metadataBeanExample.createCriteria();
        criteria.andPathEqualTo(metadataBean.getPath()).andNameEqualTo(metadataBean.getName());
        List<MetadataBean> metadataBeanList = metadataBeanMapper.selectByExample(metadataBeanExample);
        int i = 0;
        if (!Objects.isNull(metadataBeanList)) {
            i += metadataBeanList.size();
        }
        MetadataBeanExample.Criteria criteria1 = metadataBeanExample.createCriteria();
        criteria.andPathEqualTo(metadataBean.getPath()).andChinesenameEqualTo(metadataBean.getChinesename());
        List<MetadataBean> metadataBeanList1 = metadataBeanMapper.selectByExample(metadataBeanExample);
        if (!Objects.isNull(metadataBeanList1)) {
            i += metadataBeanList1.size();
        }
        if (i > 0)
            return 0;

        return metadataBeanMapper.insert(metadataBean);
    }

    private boolean isExistPath(String path) {
        return false;
    }

    /***
     * @Description: 删除节点及子节点
     *
     * @Param:
     * @return:
     * @Author: cjw
     * @Date: 2020-05-11 16:25:29
     */
    @Transactional
    public int deleteNode(MetadataBean metadataBean) {
        // 删除当前节点
        int i = 0;
        MetadataBeanExample metadataBeanExample = new MetadataBeanExample();
        MetadataBeanExample.Criteria criteria = metadataBeanExample.createCriteria();
        criteria.andPathEqualTo(metadataBean.getPath()).andNameEqualTo(metadataBean.getName()).andChinesenameEqualTo(metadataBean.getChinesename());
        i = metadataBeanMapper.deleteByExample(metadataBeanExample);
        // 删除子节点
        String path = metadataBean.getPath() + metadataBean.getName() + "/%";
        MetadataBeanExample metadataBeanExample2 = new MetadataBeanExample();
        MetadataBeanExample.Criteria criteria2 = metadataBeanExample2.createCriteria();
        criteria2.andPathLike(path);
        int i1 = metadataBeanMapper.deleteByExample(metadataBeanExample2);

        return i;
    }

    /***
     * @Description: 查询所有子节点
     * @Param:
     * @return:
     * @Author: cjw
     * @Date: 2020-05-12 12:27:26
     */
    public List<MetadataBean> getAllChildrenNodes(MetadataBean metadataBean) {
        String path = metadataBean.getPath() + metadataBean.getName() + "/%";
        MetadataBeanExample metadataBeanExample2 = new MetadataBeanExample();
        MetadataBeanExample.Criteria criteria2 = metadataBeanExample2.createCriteria();
        criteria2.andPathLike(path);
        return metadataBeanMapper.selectByExample(metadataBeanExample2);
    }

    /***
     * @Description: 修改节点的中文名, 英文名
     * 开启事务
     * 检查该节点是否存在
     * 先递归修改及其所有子节点信息(通过未更新前的path字段搜索所有子节点并更新path)
     * 后修改该节点信息
     * @Param:
     * @return:
     * @Author: cjw
     * @Date: 2020-05-12 11:30:13
     */
    @Transactional
    public int editNode(MetadataBean metadataBean) {
        // 检查该节点是否存在
        if (!isExitNode(metadataBean))
            return 0;
        // 更新所有子节点的path
        updateChildrenPath(metadataBean);
        // 修改该节点信息
        int i = metadataBeanMapper.updateByPrimaryKey(metadataBean);

        return i;
    }

    /***
     * @Description: 更新所有子节点的path
     * 查找所有子节点更新path,并递归执行本方法
     * @Param:
     * @return:
     * @Author: cjw
     * @Date: 2020-05-12 12:34:54
     */
    private int updateChildrenPath(MetadataBean metadataBean) {
        if (!isExitNode(metadataBean))
            return 0;
        // 查找所有子节点更新path,并递归执行本方法
        int i = 0;
        MetadataBean old = metadataBeanMapper.selectByPrimaryKey(metadataBean.getId()); // 找到还未更新的节点
        List<MetadataBean> allChildrenNodes = getChildrenNodes(old);
        if (!Objects.isNull(allChildrenNodes) && allChildrenNodes.size() > 0) {
            String path = metadataBean.getPath() + metadataBean.getName() + "/";
            for (MetadataBean childrenNode : allChildrenNodes) { // 先更新子节点,再更新本节点,如果先更新本节点,将找不到子节点
                childrenNode.setPath(path);
                editNode(childrenNode);
                i += metadataBeanMapper.updateByPrimaryKey(childrenNode);
            }
        }
        return i;
    }

    /***
     * @Description: 获取一级子节点
     * @Param:
     * @return:
     * @Author: cjw
     * @Date: 2020-05-12 13:43:10
     */
    public List<MetadataBean> getChildrenNodes(MetadataBean metadataBean) {
        String path = metadataBean.getPath() + metadataBean.getName() + "/";
        MetadataBeanExample metadataBeanExample2 = new MetadataBeanExample();
        MetadataBeanExample.Criteria criteria2 = metadataBeanExample2.createCriteria();
        criteria2.andPathLike(path);
        return metadataBeanMapper.selectByExample(metadataBeanExample2);
    }

    /***
     * @Description: 判断节点是否存在
     * @Param:
     * @return:
     * @Author: cjw
     * @Date: 2020-05-12 12:16:26
     */
    private boolean isExitNode(MetadataBean metadataBean) {
        MetadataBean metadataBean1 = metadataBeanMapper.selectByPrimaryKey(metadataBean.getId());
        if (Objects.isNull(metadataBean1))
            return false;
        else
            return true;
    }

    /***
     * @Description: 通过name获取所有子项
     * 提供name获取该节点
     * 拼接该节点的子节点的path值
     * 通过path值找到所有子节点并返回
     * @Param:
     * @return:
     * @Author: cjw
     * @Date: 2020-05-25 10:24:36
     */
    public List<MetadataBean> getMetaDateByName(String name) {
        MetadataBeanExample metadataBeanExample = new MetadataBeanExample();
        MetadataBeanExample.Criteria criteria = metadataBeanExample.createCriteria();
        criteria.andChinesenameEqualTo(name);
        List<MetadataBean> metadataBeanList = metadataBeanMapper.selectByExample(metadataBeanExample);
        if(Objects.isNull(metadataBeanList) || metadataBeanList.size() == 0)
            return null;
        MetadataBean metadataBean = metadataBeanList.get(0);
        String path = metadataBean.getPath();
        String path2 = path + metadataBean.getName() + "/";
        return getMetaDateByPath(path2);
    }


    /***
     * @Description: 获取所有同值path
     * @Param:
     * @return:
     * @Author: cjw
     * @Date: 2020-05-25 10:24:36
     */
    public List<MetadataBean> getMetaDateByPath(String path) {
        MetadataBeanExample metadataBeanExample = new MetadataBeanExample();
        MetadataBeanExample.Criteria criteria = metadataBeanExample.createCriteria();
        criteria.andPathEqualTo(path);
        return metadataBeanMapper.selectByExample(metadataBeanExample);
    }













}